import COS from 'cos-js-sdk-v5';

import EXIF from './exif';
import { sleep } from './util';

const GAPI = WPT.Util.handleApi(
    {
        getTempKeys: '/wechat/v1.0/sts/get-temp-keys',
    },
    { useGoApi: true }
);

export class UploadImg {
    constructor(option) {
        this.option = {
            success: option.success || (() => {}),
            imgLimit: option.imgLimit,
            isCut: option.isCut,
            files: option.files,
        };

        this.input = document.createElement('input');
        this.picIndex = 0;
        this.files = [];
        this.imgsInfo = [];
        this.setCos();

        if (this.option.files) {
            this.files = this.option.files;
            this.upload();
        } else {
            this.createFrom();
        }
    }

    createFrom() {
        const PC = !!navigator.platform.match(/mac|win/i);
        this.input.type = 'file';
        this.input.accept = PC ? 'image/jpeg, image/png, image/jpg, image/gif' : 'image/*';
        this.input.name = 'FileContent';
        this.input.multiple = this.option.imgLimit > 1;
        this.input.style.cssText = 'position: fixed; height:1em; width:1em; opacity:1 ; top:-100em; left:0;';
        this.input.id = 'from_id';
        document.body.appendChild(this.input);
        this.input.onchange = () => {
            this.isMultiPic();
            document.body.removeChild(this.input);
        };
        this.input.click();
    }

    async isMultiPic() {
        this.files = [...this.input.files].slice(0, Math.min(this.option.imgLimit, this.input.files.length));
        const noPass = [];
        let noSuport = false;

        if (noSuport) {
            this.files = this.files.filter((file, index) => {
                if (file.type === 'image/webp') {
                    noPass.push(index + 1);
                    noSuport = true;
                }
                return file.type !== 'image/webp';
            });
            WPT.Modal.tips(`webp图片格式不支持, 已经过滤第${noPass.join(',')}张图片！`, { time: 1500 });
            await sleep(1500);
        }

        if (this.option.isCut && WPT.cut) {
            // 去剪切图片，然后上传，图片剪切暂不支持多图
            WPT.cut(this.files[0], (file) => {
                this.files = [file];
                this.upload();
            });
        } else {
            this.upload();
        }
    }

    upload() {
        // 如果有一张图片大小大于10M，都不执行上传
        const execUpload = ![...this.files].some((file, index) => {
            if (file.size > 10 * 1024 * 1024) {
                WPT.Modal.tips(`第${index + 1}张图片大于10兆<br>请重新上传`, { time: 3000 });
                return true;
            }
            return false;
        });

        execUpload && this.multi();
    }

    multi() {
        const { files, picIndex } = this;
        const MAX = files.length;

        if (picIndex >= MAX) {
            WPT.Modal.loading.close();
            this.option.success(this.imgsInfo, files);
        } else {
            WPT.Modal.loading(`正在上传 ${picIndex + 1} / ${MAX}`, { mask: true });
            this.uploadImgObject(files[picIndex], picIndex);
        }
    }

    setCos() {
        this.cos = new COS({
            getAuthorization: (options, callback) => {
                // 异步获取签名
                WPT.getData(GAPI.getTempKeys, (res) => {
                        if (res.code != 0) {
                            WPT.Modal.loading('error：获取签名失败', { time: 2000 });
                            return;
                        }
                        this.initData = res.data;
                        callback({
                            TmpSecretId: res.data.credentials.tmpSecretId,
                            TmpSecretKey: res.data.credentials.tmpSecretKey,
                            XCosSecurityToken: res.data.credentials.sessionToken,
                            ExpiredTime: res.data.expiredTime,
                        });
                    }
                );
            },
        });
    }

    // 调用腾讯云api上传
    uploadImgObject(file, index) {
        const key = [8, 4, 4, 4, 12].map(WPT.Util.uuid).join('-').toLowerCase();
        this.cos.putObject(
            {
                Bucket: 'appwpt-10002380' /* 必须 */,
                Region: 'ap-shanghai' /* 必须 */,
                Key: key /* 必须 */,
                Body: file, // 上传文件对象
            },
            (err, data) => {
                if (err) {
                    // WPT.Modal.loading('error: 腾讯云上传失败', { time: 2000 });
                    // 如果腾讯云cos上传失败，重置cos，上传失败的原因一般是签名过期了
                    setTimeout(() => {
                        this.setCos();
                        this.uploadImgObject(file, index);
                    }, 2000);
                    // 上报错误
                    WPT.reportError(
                        {
                            type: 'pcUploadImgFail',
                            response: err,
                            data: this.initData,
                        },
                        false
                    );
                    return;
                }

                this.getImgInfo(
                    key,
                    file,
                    data,
                    (info) => {
                        this.imgsInfo[index] = {
                            ...data,
                            // 暂时把流量切换到image，因此cos的费用有点高
                            Location: `${window.location.protocol}//${data.Location.replace(
                                'cos.ap-shanghai',
                                'image'
                            )}`,
                            fileid: key,
                            info: {
                                height: Number(info.height),
                                width: Number(info.width),
                            },
                        };

                        this.picIndex = index + 1;
                        try {
                            EXIF.getData(file, () => {
                                this.imgsInfo[index].orientation = file.exifdata.Orientation || 1;
                                this.multi();
                            });
                        } catch (e) {
                            this.multi();
                        }
                    },
                    3
                );
            }
        );
    }

    // 获取图片信息
    getImgInfo = (key, file, data, success, countdown) => {
        const timeout = 1000 * (-2 * countdown + 7); // 1, 3, 5
        const report = (response) => {
            WPT.Modal.fail('error：图片信息获取失败');
            WPT.reportError(
                {
                    type: 'getUploadImgInfoFail',
                    response,
                    key,
                    data,
                },
                false
            );
        };

        const handleFail = (res) => {
            const img = document.createElement('img');
            img.src = URL.createObjectURL(file);
            img.onload = () => {
                success({
                    height: img.naturalHeight,
                    width: img.naturalWidth,
                });
            };
            img.onerror = () => {
                report(res);
            };
        };

        setTimeout(
            () =>
                $.ajax({
                    url: `//appwpt-10002380.image.myqcloud.com/${key}?imageInfo`,
                    dataType: 'json',
                    success: (res) => {
                        const info = res;
                        // 宽高必须存在，否则视为图片信息获取失败
                        if (info.width && info.height) {
                            success(info);
                        } else {
                            if (countdown !== 1) {
                                this.getImgInfo(key, file, data, success, countdown - 1);
                                return;
                            }
                            handleFail(res);
                        }
                    },
                    error: (err) => {
                        if (countdown !== 1) {
                            this.getImgInfo(key, file, data, success, countdown - 1);
                            return;
                        }
                        handleFail(err);
                    },
                }),
            timeout
        );
    };
}

window.pcUploadImg = (option) => new UploadImg(option);

export default (callback, imgLimit, isCut, openRemote, files, addMD5, getFile) => {
    window.pcUploadImg({
        success(imgs, sfiles) {
            const serverIds = [];
            const localIds = [];
            let serverId = '';
            let date = new Date();
            if (WPT && WPT.nowTime) {
                date = new Date(WPT.nowTime * 1000);
            }
            const year = date.getFullYear();
            const month = (date.getMonth() + 1).toString();
            const day = date.getDate();
            const fileInfos = [];

            imgs.forEach((item, index) => {
                const o = item.orientation;
                const needSwapWH = o === 6 || o === 8;
                const info = item.info;
                const width = needSwapWH ? info.height : info.width;
                const height = needSwapWH ? info.width : info.height;

                serverId = `${year + (month > 9 ? month : `0${month}`) + (day > 9 ? day : `0${day}`)}${
                    item.fileid
                }-W${width}H${height}`;

                if (addMD5 && item.ETag) {
                    serverId += `|md5-${item.ETag}`;
                }

                fileInfos.push({
                    name: serverId,
                    file: sfiles[index],
                });
                serverIds.push(serverId);
                localIds.push(`${item.Location}?imageMogr2/auto-orient#W${width}H${height}`);
            });

            if (getFile) {
                callback(serverIds, localIds, fileInfos);
            } else {
                callback(serverIds, localIds);
            }
        },
        imgLimit: imgLimit || 9,
        isCut,
        files,
    });
};
